﻿using DatabaseTransfer.Connections;
using DatabaseTransfer.Tables;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseTransfer.Interfaces
{
    /// <summary>
    /// Base abstract class that defines methods used to connect to databaes
    /// </summary>
    public abstract class AbstractDatabase
    {
        /// <summary>
        /// The connection information to the database
        /// </summary>
        public DatabaseConnector Connector { get; private set; }

        /// <summary>
        /// Base constructor
        /// </summary>
        /// <param name="connector"></param>
        public AbstractDatabase(DatabaseConnector connector)
        {
            this.Connector = connector;
        }

        /// <summary>
        /// Constructor used for deseralizing the class
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        public AbstractDatabase(SerializationInfo info, StreamingContext context)
        {
            this.Connector = (DatabaseConnector)info.GetValue("Connector", typeof(DatabaseConnector));
        }

        /// <summary>
        /// Connect to the dabase
        /// </summary>
        /// <returns>True if the database connection was successful, false otherwise</returns>
        abstract public bool Connect();

        /// <summary>
        /// Disconnect to the database
        /// </summary>
        /// <returns>True if the database disconnection was successful, false otherwise</returns>
        abstract public bool Disconnect();

        /// <summary>
        /// Get available tables from the database
        /// </summary>
        /// <returns>List of tables in the database</returns>
        abstract public List<Table> GetAvailableTables();

        /// <summary>
        /// Gets the columns from the selected table
        /// </summary>
        /// <param name="tableName">Name of the table to retrieve the columns</param>
        /// <returns>List of the columns</returns>
        abstract public List<TableColumn> GetTableColumns(string tableName);

        /// <summary>
        /// Creates and executes a query to get the data for the selected columns
        /// </summary>
        /// <param name="tableName">Name of the table to get the data from</param>
        /// <param name="columns">Columns within the table to get the data from</param>
        /// <returns></returns>
        abstract public TableResults GetData(string tableName, List<TableColumn> columns);

        /// <summary>
        /// Constructs an insert statement to execute and insert the data
        /// </summary>
        /// <param name="tableName">Name of the table to insert data into</param>
        /// <param name="columns">Colums within the table to insert into</param>
        /// <param name="results">The data to use to insert</param>
        /// <returns></returns>
        abstract public bool WriteData(string tableName, List<TableColumn> columns, TableResults results);
    }
}
